﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel.DomainServices.Client;
using ProjectenArtesis.Web;
using System.Windows.Browser;
using System.Diagnostics;


namespace ProjectenArtesis
{
    public partial class MainPage : UserControl
    {
        #region Constanten
        private const int AANTAL_VAKKEN = 11;
        private const int ALPHA_CHANNEL = 255;
        private const int BUTTONS_NEXT_TO_EACHOTHER = 5;
        private const int LEFT_BEGIN = -500;
        private const int TOP_BEGIN = 80;
        private const int MOVEMENT_X = 135;
        private const int MOVEMENT_Y = 0;
        private const int BUTTON_WIDTH = 125;
        private const int BUTTON_HEIGHT = 124;
        private const int ROW_MOVEMENT = 20;
        #endregion

        public enum pageType
	    {
	        Schooljaar,
            BamaType,
            Opleiding,
            Traject,
            Deeltraject,
            BameBack,
	    }

        private int color_counter;
        private List<Color> postitColors = new List<Color>();
        
        private List<HyperlinkButton> navigationButtons = new List<HyperlinkButton>();
        private List<Label> navihaakjesLabels = new List<Label>();
        private List<Button> postitList = new List<Button>();
        private string currentSchooljaar = "";
        private int currentBamaType = 0;
        private int currentOpleidingsId = 0;
        private int currentTraject = 0;
        private int currentDeeltraject = 0;


        #region Postit Colors
        private Color postitOrange;
        private Color postitRed;
        private Color postitDarkred;
        private Color postitViolet;
        private Color postitBlue;
        private Color postitLightblue;
        private Color postitTurqouise;
        private Color postitGreen;
        #endregion

        #region Studiepunten Colors
        private SolidColorBrush bgOrange = new SolidColorBrush(Color.FromArgb(255, 255, 128, 0));
        private SolidColorBrush whiteColor = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
        private SolidColorBrush blackFont = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
        private SolidColorBrush redishColor = new SolidColorBrush(Color.FromArgb(255, 255, 12, 0)); 
        #endregion

        ArtesisDomainContext client = new ArtesisDomainContext();
        List<Item> autoCompleteList = new List<Item>();
        StackPanel myStackpanel = new StackPanel();
        
        
        
        public MainPage()
        {
            InitializeComponent();
            #region Postit Color Initialization
            postitOrange = Color.FromArgb(ALPHA_CHANNEL, 137, 137, 10);
            postitRed = Color.FromArgb(ALPHA_CHANNEL, 240, 65, 25);
            postitDarkred = Color.FromArgb(ALPHA_CHANNEL, 186, 13, 14);
            postitViolet = Color.FromArgb(ALPHA_CHANNEL, 145, 18, 170);
            postitBlue = Color.FromArgb(ALPHA_CHANNEL, 0, 42, 235);
            postitLightblue = Color.FromArgb(ALPHA_CHANNEL, 15, 113, 244);
            postitTurqouise = Color.FromArgb(ALPHA_CHANNEL, 15, 152, 118);
            postitGreen = Color.FromArgb(ALPHA_CHANNEL, 97, 163, 12);

            this.postitColors.Add(this.postitOrange);
            this.postitColors.Add(this.postitRed);
            this.postitColors.Add(this.postitDarkred);
            this.postitColors.Add(this.postitViolet);
            this.postitColors.Add(this.postitBlue);
            this.postitColors.Add(this.postitLightblue);
            this.postitColors.Add(this.postitTurqouise);
            this.postitColors.Add(this.postitGreen);
            #endregion

            this.color_counter = 0;
            fillSchooljaar(client);
            fillAutoComplete(client);
            autoCompleteBox1.IsEnabled = false;
            autoCompleteBox1.Text = "...search";
        }

        #region FillAutocomplete
        public void fillAutoComplete(ArtesisDomainContext client)
        {
            var result = client.Load<SA_OpleidingID>(client.GetSA_OpleidingIDQuery(), (variabele) =>
            {
                foreach (var item in variabele.Entities)
                {
                    autoCompleteList.Add(new Item() { Id = item.p_opleidingID, Name = item.actomschrijving });
                }
            }, true);
        }
        private void fillAutoCompleteOpleidingen(ArtesisDomainContext client, String schooljaar)
        {
            List<Item> items = new List<Item>();
            EntityQuery<SA_Opleiding> opleidingen = client.GetOpleidingenBySchooljaarQuery(schooljaar);

            var result = client.Load<SA_Opleiding>(opleidingen, (opl) =>
            {
                foreach (var o in opl.Entities)
                {
                    items.Add(new Item() { Id = o.p_opleiding, Name = o.opleidingNL });
                }
                autoCompleteList = items;
            }, true);
        }
        #endregion

        #region fillButtons
        private void fillSchooljaar(ArtesisDomainContext client)
        {
            loop.Begin();
            List<Item> schooljarenItems = new List<Item>();
            EntityQuery<SA_Schooljaar> schooljarenQuery = client.GetSchooljarenQuery();
            var result = client.Load<SA_Schooljaar>(schooljarenQuery, (schooljaren) =>
            {
                foreach (var jaar in schooljaren.Entities)
                {
                    schooljarenItems.Add(new Item() {Name = jaar.schooljaar });
                }
                CreateButtons(schooljarenItems,pageType.Schooljaar);
                loop.Stop();
                loaderGrid.Visibility=Visibility.Collapsed;
            }, true);
        }
        private void fillBamaTypes(ArtesisDomainContext client, String schooljaar)
        {
            loop.Begin();
            loaderGrid.Visibility = Visibility.Visible;
            List<Item> items = new List<Item>();
            EntityQuery<SA_BamaType> queryBamatypes = client.GetBamaTypesQuery(schooljaar);
            var result = client.Load<SA_BamaType>(queryBamatypes, (types) =>
            {
                foreach (var type in types.Entities)
                {
                    items.Add(new Item() { Id = type.p_bamatype, Name = type.bamatypeafdrukNL});
                }
                CreateButtons(items, pageType.BamaType);
                loop.Stop();
                loaderGrid.Visibility = Visibility.Collapsed;
            }, true);
        }
        private void fillOpleidingen(ArtesisDomainContext client, String schooljaar, int p_bamatype)
        {
            loop.Begin();
            loaderGrid.Visibility = Visibility.Visible;
            List<Item> items = new List<Item>();
            EntityQuery<SA_Opleiding> opleidingenQuery = client.GetOpleidingenQuery(schooljaar, p_bamatype);

            var result = client.Load<SA_Opleiding>(opleidingenQuery, (opleidingen) =>
            {
                foreach (var opleiding in opleidingen.Entities)
                {
                    items.Add(new Item() { Id = opleiding.p_opleiding, Name = opleiding.opleidingNL });
                }
                CreateButtons(items, pageType.Opleiding);
                loop.Stop();
                loaderGrid.Visibility = Visibility.Collapsed;
            }, true);
        }
        private void fillTrajecten(ArtesisDomainContext client, int p_opleiding)
        {
            loop.Begin();
            loaderGrid.Visibility = Visibility.Visible;
            List<Item> items = new List<Item>();
            EntityQuery<SA_OpleidingTraject> trajectenQuery = client.GetOpleidingTrajectenQuery(p_opleiding);

            var result = client.Load<SA_OpleidingTraject>(trajectenQuery, (trajecten) =>
            {
                foreach (var traject in trajecten.Entities)
                {
                    items.Add(new Item() { Id = traject.p_opltraject, Name = traject.opleidingstrajectNL });
                }
                CreateButtons(items, pageType.Traject);
                loop.Stop();
                loaderGrid.Visibility = Visibility.Collapsed;
            }, true);
        }
        private void fillDeeltrajecten(ArtesisDomainContext client, int p_opltraject)
        {
            loop.Begin();
            loaderGrid.Visibility = Visibility.Visible;
            List<Item> items = new List<Item>();
            EntityQuery<SA_DeelTraject> deeltrajectenQuery = client.GetDeeltrajectenQuery(p_opltraject);

            var result = client.Load<SA_DeelTraject>(deeltrajectenQuery, (deeltrajecten) =>
            {
                foreach (var deeltraject in deeltrajecten.Entities)
                {
                    items.Add(new Item() { Id = deeltraject.p_deeltraject, Name = deeltraject.deeltrajectNL });
                }
                CreateButtons(items, pageType.Deeltraject);
                loop.Stop();
                loaderGrid.Visibility = Visibility.Collapsed;
            }, true);
        }
        private void fillOLODS(ArtesisDomainContext client, int p_opleiding, int p_deeltraject)
        {
            loop.Begin();
            loaderGrid.Visibility = Visibility.Visible;
            EntityQuery<Item> olodsQuery = client.GetOLODSQuery(p_deeltraject, p_opleiding);

            OlodStructuur.MakeOrderedOlodStructuur(client,olodsQuery, this);
            // this wordt meegegeven, zodat de andere methode GenerateOlodView kan aanroepen
            // (anders problemen met Deferred Execution)
            
            //LayoutRoot.Children.Add(myStackpanel);
        }
        #endregion

        #region Event handlers autocompleteBox
        private void autoCompleteBox1_GotFocus(object sender, RoutedEventArgs e)
        {
            autoCompleteBox1.ItemsSource = autoCompleteList;
        }

        private void autoCompleteBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (autoCompleteBox1.SelectedItem != null)
            {
                Item opl = (Item) autoCompleteBox1.SelectedItem;
                currentOpleidingsId = opl.Id;
                fillTrajecten(client, opl.Id);
                RemoveButtons(postitList);
            }
        }
        #endregion


        public void CreateButtons(List<Item> items, pageType type)
        {
            int left = LEFT_BEGIN;
            int top = TOP_BEGIN;

            for (int i = 0; i < items.Count; i++)
            {
                //opvragen knop achtergrondkleur.
                SolidColorBrush bgBrush = new SolidColorBrush(this.GiveColor());
                SolidColorBrush fontBrush = new SolidColorBrush(Color.FromArgb(ALPHA_CHANNEL, 255, 255, 255));
                Button newPostIt = new Button() { 
                    Background = bgBrush,
                    //opvragen van content
                    Content = items[i].Name,
                    Tag = items[i].Id,
                    Width = BUTTON_WIDTH,
                    Height = BUTTON_HEIGHT,
                    Foreground = fontBrush,
                    VerticalAlignment = VerticalAlignment.Top,
                    //customstyle aan knop toevoegen
                    Style = (Style)this.Resources["ButtonStyle1"] };

                switch (type)
	            {
                    case pageType.Schooljaar:
                        newPostIt.Click += new RoutedEventHandler(OnSchooljaarClick);
                        break;
                    case pageType.BamaType:
                        newPostIt.Click += new RoutedEventHandler(OnBamaTypeClick);
                        break;
                    case pageType.Opleiding:
                        newPostIt.Click += new RoutedEventHandler(OnOpleidingClick);
                        break;
                    case pageType.Traject:
                        newPostIt.Click += new RoutedEventHandler(OnTrajectClick);
                        break;
                    case pageType.Deeltraject:
                        newPostIt.Click += new RoutedEventHandler(OnDeeltrajectClick);
                        break;
		            default:
                break;
	            }
                
                
                //om de zoveel knoppen, op volgende lijn zetten
                if ((i != 0) && (i % BUTTONS_NEXT_TO_EACHOTHER < 1))
                {
                    left = LEFT_BEGIN;
                    top += BUTTON_HEIGHT + MOVEMENT_Y;
                }

                //knop positioneren
                newPostIt.Margin = new Thickness(left, top, 0, 0);
                postitList.Add(newPostIt);
                LayoutRoot.Children.Add(newPostIt);

                //knop per knop verplaatsen
                left += BUTTON_WIDTH + MOVEMENT_X;
            }
        }
        private void RemoveButtons(List<Button> buttonlist)
        {
            foreach (Button button in buttonlist)
            {
                LayoutRoot.Children.Remove(button);
            }
            buttonlist.Clear();
        }

        #region NaviEventHandlers
        private void OnSchooljaarNaviClick(object sender, RoutedEventArgs e)
        {
            navigationStackPanel.Children.Clear();
            autoCompleteBox1.IsEnabled = false;
            LayoutRoot.Children.Remove(myStackpanel);
            RemoveButtons(postitList);
            fillSchooljaar(client);

        }
        private void OnBamaTypeNaviClick(object sender, RoutedEventArgs e)
        {
            this.CommonOnNaviClick(((HyperlinkButton)sender));
            fillBamaTypes(client, currentSchooljaar);
        }
        private void OnOpleidingNaviClick(object sender, RoutedEventArgs e)
        {
            this.CommonOnNaviClick(((HyperlinkButton)sender));
            fillOpleidingen(client, currentSchooljaar, currentBamaType);
        }
        private void OnTrajectNaviClick(object sender, RoutedEventArgs e)
        {
            this.CommonOnNaviClick(((HyperlinkButton)sender));
            fillTrajecten(client,currentOpleidingsId);
        }
        private void OnDeeltrajectNaviClick(object sender, RoutedEventArgs e)
        {
            this.CommonOnNaviClick(((HyperlinkButton)sender));
            fillDeeltrajecten(client,currentTraject);
        }
        private void OnInfoNaviClick(object sender, RoutedEventArgs e)
        {
            this.CommonOnNaviClick(((HyperlinkButton)sender));
            fillOLODS(client, currentOpleidingsId, currentDeeltraject);
        }
        private void CommonOnNaviClick(HyperlinkButton button)
        {
            RemoveNavigationButtons(button);
            LayoutRoot.Children.Remove(myStackpanel);
            RemoveButtons(postitList);
        }
        #endregion

        private void generateNaviItem(string text, string tag, RoutedEventHandler evt)
        {
            HyperlinkButton naviButton = new HyperlinkButton() { 
                Content = text,
                Tag = tag,
                Foreground = new SolidColorBrush(Colors.Orange) };
            naviButton.Click += evt;
            navigationButtons.Add(naviButton);

            Label haakjeLabel = new Label() { 
                Content = ">"
            };
            navihaakjesLabels.Add(haakjeLabel);

            navigationStackPanel.Children.Add(naviButton);
            navigationStackPanel.Children.Add(haakjeLabel);
        }

        #region onClickEventsButtons
        private void OnSchooljaarClick(object sender, RoutedEventArgs e)
        {
            Button postit = (Button)sender;
            RemoveButtons(postitList);
            currentSchooljaar = postit.Content.ToString();
            fillBamaTypes(client,currentSchooljaar);
            fillAutoCompleteOpleidingen(client, currentSchooljaar);
            autoCompleteBox1.IsEnabled = true;

            generateNaviItem(currentSchooljaar, currentSchooljaar, new RoutedEventHandler(OnSchooljaarNaviClick));
            
        }
        private void OnBamaTypeClick(object sender, RoutedEventArgs e)
        {
            Button postit = (Button)sender;
            RemoveButtons(postitList);
            currentBamaType = int.Parse(postit.Tag.ToString());
            fillOpleidingen(client,currentSchooljaar, int.Parse(postit.Tag.ToString()));

            generateNaviItem(postit.Content.ToString(), postit.Tag.ToString(), new RoutedEventHandler(OnBamaTypeNaviClick));

        }
        private void OnOpleidingClick(object sender, RoutedEventArgs e)
        {
            Button postit = (Button)sender;
            RemoveButtons(postitList);
            currentOpleidingsId = int.Parse(postit.Tag.ToString());
            fillTrajecten(client, currentOpleidingsId);

            generateNaviItem(postit.Content.ToString(), postit.Tag.ToString(), new RoutedEventHandler(OnOpleidingNaviClick));

        }
        private void OnTrajectClick(object sender, RoutedEventArgs e)
        {
            Button postit = (Button)sender;
            RemoveButtons(postitList);
            currentTraject = int.Parse(postit.Tag.ToString());
            fillDeeltrajecten(client, int.Parse(postit.Tag.ToString()));

            generateNaviItem(postit.Content.ToString(), postit.Tag.ToString(), new RoutedEventHandler(OnTrajectNaviClick));
        }
        private void OnDeeltrajectClick(object sender, RoutedEventArgs e)
        {
            Button postit = (Button)sender;
            RemoveButtons(postitList);
            currentDeeltraject = int.Parse(postit.Tag.ToString());
            fillOLODS(client, currentOpleidingsId, int.Parse(postit.Tag.ToString()));

            generateNaviItem(postit.Content.ToString(), postit.Tag.ToString(), new RoutedEventHandler(OnDeeltrajectNaviClick));
        }
        #endregion

        public Color GiveColor()
        {
            //int counter;

            if (this.color_counter >= postitColors.Count)
                this.color_counter = 0;

            //counter = this.color_counter;
            //this.color_counter++;
            // use postfix notation: add 1 to it after assigning
            return (Color)this.postitColors[this.color_counter++];
        }

        public void RemoveNavigationButtons(HyperlinkButton sender)
        {
            bool found = false;
            int startDelete = 0;
            HyperlinkButton linkButton = sender;
            for (int i = 0; i < navigationButtons.Count; i++)
            {
                
                if (linkButton.Equals(navigationButtons[i]))
                {
                    found = true;
                    startDelete = i;
                }
                if (found)
                {
                    navigationStackPanel.Children.Remove(navigationButtons[i]);
                    navigationStackPanel.Children.Remove(navihaakjesLabels[i]);
                }
            }
            navigationButtons.RemoveRange(startDelete, navigationButtons.Count() - startDelete);
            navihaakjesLabels.RemoveRange(startDelete, navihaakjesLabels.Count() - startDelete);
            removeResult();
        }

        private void clbtestButton_Click(object sender, RoutedEventArgs e)
        {
            TestClb testClb = new TestClb();
            testClb.Show();
        }

        internal void GenerateOlodView(List<OlodStructuur> structuren)
        {
            // Artesis-logo is reeds aan het draaien -- zie fillOLODS()
            #region Header
            //create grid
            Grid header = new Grid() { 
                Margin = new Thickness(0, 85, 0, 0),
                Width = 375,
                Height = 51,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Top,
                Background = bgOrange,
                Name = "headerResult"
            };

            //fill grid     
            // jaar
            header.Children.Add(new TextBlock() { 
                Width = 100,
                Height = 29,
                Margin = new Thickness(10, 6, 0, 0),
                Foreground = whiteColor,
                Text = navigationButtons.Last().Content.ToString(),
                FontWeight = FontWeights.Bold,
                VerticalAlignment = VerticalAlignment.Top,
                HorizontalAlignment = HorizontalAlignment.Left
            });
            
            // whitebar
            header.Children.Add(new Rectangle() { 
                Height = 24,
                Fill = whiteColor,
                Margin = new Thickness(0, 27, 0, 0),
                VerticalAlignment = VerticalAlignment.Top
            });
 
            // opleidingsonderdelen
            header.Children.Add(new TextBlock() { 
                Margin = new Thickness(9, 31, 0, 0),
                Foreground = redishColor,
                Text = "opleidingsonderdelen",
                FontWeight = FontWeights.Bold,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top
            });

            // studiepunten
            header.Children.Add(new TextBlock() { 
                Margin = new Thickness(0, 31, 9, 0),
                Foreground = redishColor,
                Text = "studiepunten",
                FontWeight = FontWeights.Bold,
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top
            });
            #endregion

            //create grid
            Grid olodContent = new Grid() { 
                HorizontalAlignment = HorizontalAlignment.Center,
                Margin = new Thickness(0, 136, 0, 0),
                Background = bgOrange,
                Name = "olodResult",
                Width = 375 };

            int rowMovement = 5;
            int separatorMovement = 0;
            foreach (OlodStructuur structuur in structuren)
            {
                //hoofdopleidingsonderdeel naam
                olodContent.Children.Add(new HyperlinkButton() { 
                    Height = 20,
                    Margin = new Thickness(9, rowMovement, 0, 0),
                    Content = structuur.HoofdOlod.Name,
                    NavigateUri = new Uri("http://desk.artesis.be/bamaflexweb/BMFUIDetailxOLOD.aspx?a=" + structuur.HoofdOlod.Id + "&b=2&c=1"),
                    Foreground = whiteColor,
                    FontWeight = FontWeights.Bold,
                    VerticalAlignment = VerticalAlignment.Top
                });

                //punten bij hoofdopleidingsonderdeel
                olodContent.Children.Add(new TextBlock() { 
                    Width = 69,
                    Height = 20,
                    Margin = new Thickness(0, rowMovement, 9, 0),
                    Foreground = whiteColor,
                    Text = structuur.HoofdOlod.Studiepunten.ToString(),
                    TextAlignment = TextAlignment.Center,
                    HorizontalAlignment = HorizontalAlignment.Right,
                    VerticalAlignment = VerticalAlignment.Top
                });

                if (structuur.DeelOlods.Count > 0)
                {
                    rowMovement += ROW_MOVEMENT;

                    foreach (var dolodItem in structuur.DeelOlods)
                    {
                        //deel opleidingsonderdeel naam
                        olodContent.Children.Add(new HyperlinkButton() { 
                            Height = 20,
                            Margin = new Thickness(19, rowMovement, 0, 0),
                            Content = dolodItem.Name,
                            NavigateUri = new Uri("http://desk.artesis.be/bamaflexweb/BMFUIDetailxOLOD.aspx?a=" + dolodItem.Id + "&b=2&c=1"),
                            TargetName = "_blank",
                            Foreground = blackFont,
                            VerticalAlignment = VerticalAlignment.Top
                        });

                        //deel opleidingsonderdelen studiepunten
                        olodContent.Children.Add(new TextBlock() {
                            Width = 69,
                            Height = 20,
                            Margin = new Thickness(0, rowMovement, 9, 0),
                            Foreground = blackFont,
                            Text = dolodItem.Studiepunten.ToString(),
                            TextAlignment = TextAlignment.Center,
                            HorizontalAlignment = HorizontalAlignment.Right,
                            VerticalAlignment = VerticalAlignment.Top
                        });


                        rowMovement += ROW_MOVEMENT;
                    }
                }
                else
                {
                    rowMovement += ROW_MOVEMENT;
                }

                separatorMovement = rowMovement;

                //lijntje als onderscheiding tussen olods (= separator)
                olodContent.Children.Add(new Rectangle() { 
                    Fill = whiteColor,
                    Height = 1,
                    Margin = new Thickness(9, separatorMovement, 8, 0),
                    VerticalAlignment = VerticalAlignment.Top
                });
            }

            // draaiend Artesis-logo stoppen
            loop.Stop();
            loaderGrid.Visibility = Visibility.Collapsed;
            LayoutRoot.Children.Add(header);
            LayoutRoot.Children.Add(olodContent);
        }

        private void removeResult()
        {
            for (int i = 0; i < LayoutRoot.Children.Count; i++ )
            {
                var item = LayoutRoot.Children.ElementAt(i);

                if (item.GetType().Equals((new Grid()).GetType()))
                {
                    Grid g = (Grid)item;
                    if (g.Name == "olodResult" || g.Name == "headerResult")
                    {
                        LayoutRoot.Children.Remove(g);
                        i = 0;
                    }
                }
            }
        }
    }
}
